
import logging;
class CommonException(Exception):
	def __init__(self, value):
		self.value = value
	def __str__(self):
		return repr(self.value)


class notimplementederror(Exception):
	def __init__(self, value):
		self.value = value
	def __str__(self):
		return repr(self.value)


class RequestUtil:
	def __init__(self):
		self.GETORPOST = {};
		self.despatcher = None;
		self.headers = {};
		self.SERVER = {};
		self.__response_ = [];
		self.__initialized_ = False;

	@staticmethod
	def setParams(keys, values, headers, caller):
		global requestHandler;
		requestHandler.GETORPOST = {};

		
		
		#if (requestHandler.__initialized_):
		#	return;

		i = 0;

		for key in keys:
			requestHandler.GETORPOST[key] = values[i];
			i = i+1;

		


		for keys in headers:
			requestHandler.headers[keys] = headers[keys];

		requestHandler.despatcher = caller;
		import os;
		requestHandler.SERVER = os.environ;

		requestHandler.__initialized_ = True;


	@staticmethod
	def getDespatcher():
		global requestHandler;
		return requestHandler.despatcher;


	@staticmethod
	def addResponseData(response):
		global requestHandler;
		requestHandler.__response_.append(response);

	@staticmethod
	def clearResponseData():
		global requestHandler;
		requestHandler.__response_ = [];

	@staticmethod
	def getResponseData():
		global requestHandler;
		return ''.join(requestHandler.__response_);

	@staticmethod
	def flushResponseData():
		global requestHandler;

		import time;

		for data in requestHandler.__response_:
			requestHandler.getDespatcher().response.out.write(data);

		time.sleep(10);
		requestHandler.__response_ = [];

	@staticmethod
	def getInstance():
		global requestHandler;
		return requestHandler;
	    
requestHandler = RequestUtil();

class Util:
	mapHeaders = {
			'content-type' : 'Content-Type',
			'etag' : 'ETag',
			'server': 'Server',
			'accept-ranges': 'Accept-Ranges',
			'date': 'Date',
			'p3p': 'P3P',
			'last-modified': 'Last-Modified',
			'cache-control': 'Cache-Control',

			};

	disallowedHeaders = ['content-encoding', 'content-length', 'date', 'server', 'transfer-encoding'];

	@staticmethod
	def ob_start():
		pass;

	@staticmethod
	def ob_end_clean():
		requestUtilHandler = RequestUtil.getInstance();
		requestUtilHandler.clearResponseData();

	@staticmethod
	def ob_end_flush():
		requestUtilHandler = RequestUtil.getInstance();
		requestUtilHandler.flushResponseData();

	@staticmethod
	def ob_get_contents():
		requestUtilHandler = RequestUtil.getInstance();
		
		return requestUtilHandler.getResponseData();

	@staticmethod
	def normal_path(path):
	  import os;
	  path.replace('\\',os.sep);
          return path;


	@staticmethod
	def ucwords(s):
	  arr = s.split(" ");
	  for i in range(len(arr)):
	    arr[i] = arr[i].capitalize();

	  return " ".join(arr);
	


	@staticmethod
	def array_merge (a,b):
		if(type(a).__name__ == 'dict'):
			c = a;
			if(type(b).__name__ == 'dict'):
				keys = b.keys();
			else :
				keys = range (0, len(b))
			for k in keys :
				if c.has_key(k): 
					continue;
				else: 
					c[k] = b[k];
		
		else:
			c = [];
			for k in range (0, len(a)):
				if a[k] != None: 
					b[k] = a[k];
			c = b;
		

		return c;

	@staticmethod
	def is_set(varName):
            try:
                if varName:
		    return True;
            except NameError:
               # variable not set, do something
               return False;

	@staticmethod
	def abstract():
		from lib import notimplementederror
		raise notimplementederror, 'caller must be implemented in subclass';

	@staticmethod
	def substr(subject, start = -1, end = 0):
		length = len(subject);
		if(not length or start < 0 or end < 0):
			return subject;

		if (end == 0):
			end = length - start;
		
		end = start + end;

		subject = subject[start:end];

		subject = ''.join(subject);

		return subject;

	@staticmethod
	def json_encode(encodeObject, escaped_forward_slash=False):
		#from lib import Json;
		return Json().write(encodeObject, escaped_forward_slash);
		

	@staticmethod
	def json_decode(decodedString, type = True):
		return Json().read(decodedString);
	
	@staticmethod
	def redirect(URL):
		caller = RequestUtil.getInstance().getDespatcher().redirect(URL);
		
	
	@staticmethod
	def header(response, headerString, headerValue = ""):
		if (len(headerString.strip()) == 0):
			return;

		#[temp kludge]

		if (headerString.lower() in Util.disallowedHeaders or headerString.lower().find('etag') != -1 or headerString.lower().find('expir') != -1):
			return;
		
		if (headerValue  == ''):
			headerStringArr = headerString.split(':');
			
			headerString = headerStringArr[0];
			del(headerStringArr[0]);
			headerValue  = ':'.join(headerStringArr);
			
		if Util.mapHeaders.has_key(headerString.lower()):
			headerString = Util.mapHeaders[headerString.lower()];
		else:
			headerString = Util.ucwords(headerString.replace("-", " ").lower()).replace(" ", "-");

		from lib import Logger;
		#Logger.quickLog('Header: "' + headerString + '" , value:"' + headerValue + '"');

		response.headers[headerString] = headerValue;
		
		#RequestUtil.getDespatcher().response.headers.add_header(headerString, headerValue.strip());
		#RequestUtil.getDespatcher().response.headers[headerString] =  headerValue.strip();

		#else:
			#headerString = headerString.split(':');
			#RequestUtil.getDespatcher().response.out.write(Util.mapHeaders[headerString[0].lower()] + ": " + headerString[1]);
			#headerName = Util.mapHeaders[headerString[0].lower()] if Util.mapHeaders.has_key(headerString[0].lower()) else Util.ucwords(headerString[0].lower());
			#RequestUtil.getDespatcher().response.headers[headerString[0].lower()] =  headerString[1].strip();
		

	@staticmethod
	def write(headerString):
		if (len(headerString.strip()) == 0):
			return;
		#RequestUtil.getDespatcher().response.out.write(headerString);
		requestUtilHandler = RequestUtil.getInstance();
		requestUtilHandler.addResponseData(headerString);		

		pass;

	

	@staticmethod
	def is_array(obj):
		return (type(obj).__name__ == 'list' or type(obj).__name__ == 'dict');
	
	@staticmethod
	def die():
		pass;
		#Util.ob_end_flush();
		#import sys;sys.exit();

	@staticmethod
	def xor_crypt(str1, nextstr):
		import operator;
		import StringIO;
		import base64;
		if str1.endswith("="):
			str2 = base64.b64decode(str1)
		else:
			str2 = str1
		# create two streams in memory the size of the string str2
		# one stream to read from and the other to write XOR crypted character to
		sr = StringIO.StringIO(str2)
		sw = StringIO.StringIO(str2)
		# make sure we start both streams at position zero (beginning)
		sr.seek(0)
		sw.seek(0)
		n = 0
		for k in range(len(str2)):
			# loop through password start to end and repeat
			if n >= len(nextstr) - 1:
				n = 0
			p = ord(nextstr[n])
			n += 1
			# read one character from stream sr
			c = sr.read(1)
			b = ord(c)
			# xor byte with password byte
			t = operator.xor(b, p)
			z = chr(t)
			# advance position to k in stream sw then write one character
			sw.seek(k)
			sw.write(z)
		# reset stream sw to beginning
		sw.seek(0)
		str3 = sw.read()
		if str1.endswith("="):
			return str3;
		else:
			return base64.encodestring(str3)
			
	@staticmethod
	def is_numeric(value):
		if type(value) == types.IntType:
			return True;
		else:
			try:
				int(val)
				return True;
			except:
				return False;
		

class ConfigException(Exception):
	def __init__(self, value):
		self.value = value
	def __str__(self):
		return repr(self.value)


class Config():
	config = False;

	@staticmethod
	def loadConfig ():
		
		if(Config.config == False):
			from config import ConfigContainer;
			Config.config = ConfigContainer.shindigConfig;
			import os;

			if (os.path.exists('local.py')):
				import local;
				#if ('shindigConfig' in local):
				#	Config.config = Util.array_merge(Config.config, local.config);


	@staticmethod
	def get(key):
		if (not Config.config):
			Config.loadConfig();
		if (Config.config.has_key(key)):
			return Config.config[key];
		else:
		    import ConfigException
		    raise ConfigException, "Invalid config key";


class GAEJsonException(Exception):
    pass

import string
import types
import re;

class GaeJson:
	def __init__(self):
		self.escapes = {'t':'\t','n':'\n','f':'\f','r':'\r','b':'\b'};
		self.digits = {'A': 10,'B': 11,'C': 12,'D': 13,'E': 14,'F':15};
		self._escapedForwardSlash = False;
		self.index = 0;

	def encode(self, inputObject, escapedForwardSlash=False):
		self.result = "";
		self.startEncoding(inputObject);
		self._escapedForwardSlash = escapedForwardSlash;
		return self.result;



	def startEncoding(self, inputObject):
		objectType = type(inputObject);

		if objectType is types.DictType:
			n = len(inputObject)
			self.result = self.result + "{";

			for k, v in inputObject.items():
				self.startEncoding(k)
				self.result = self.result + ":"
				self.startEncoding(v)
				n = n - 1
				if n > 0:
					self.result = self.result + ","
			self.result = self.result + "}"

		elif objectType is types.ListType or objectType is types.TupleType:
			n = len(inputObject)
			self.result = self.result + "[";
			for item in inputObject:
				self.startEncoding(item)
				n = n - 1
				if n > 0:
					self.result = self.result + ",";
			self.result = self.result + "]";

		elif objectType is types.StringType or objectType is types.UnicodeType:
			self.result = self.result + '"';
			inputObject = inputObject.replace('\\', r'\\')
			if self._escapedForwardSlash:
				inputObject = inputObject.replace('/', r'\/')
			inputObject = inputObject.replace('"', r'\"')
			inputObject = inputObject.replace('\b', r'\b')
			inputObject = inputObject.replace('\f', r'\f')
			inputObject = inputObject.replace('\n', r'\n')
			inputObject = inputObject.replace('\r', r'\r')
			inputObject = inputObject.replace('\t', r'\t')
			self.result = self.result + inputObject;
			self.result = self.result + '"';
		elif objectType is types.IntType or objectType is types.LongType:
			self.result = self.result + str(inputObject);
		elif objectType is types.FloatType:
			self.result = self.result + ("%f" % inputObject);
		elif inputObject is True:
			self.result = self.result +  "true";
		elif inputObject is False:
			self.result = self.result + "false";
		elif inputObject is None:
			self.result = self.result + "null";
		else:
			self.startEncoding(inputObject.__dict__)	


	def decode(self, inputString):
		self.inputString = GaeJson.removeCTypeComment(inputString);
		self.inputString = self.inputString.strip();

		Logger.quickLog(self.inputString);

		return self.startDecoding();

	@staticmethod
	def removeCTypeComment(text):
		def replacer(match):
			s = match.group(0);
			if s.startswith('/'):
				return "";
			else:
				return s;

		pattern = re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',re.DOTALL | re.MULTILINE);
		return re.sub(pattern, replacer, text);

	def startDecoding(self):
		start = self.start(True)		

		if start is None:
			raise GAEJsonException, "Invalid String";
		if start == '{':
			return self.decodeObject();
		elif start == '[':
			return self.decodeArray();
		elif start == '"':
			return self.decodeString();
		elif start == '-' or start.isdigit():
			return self.decodeNumber();
		elif start == 't':
			return self.decodeTrue();
		elif start == 'f':
			return self.decodeFalse();
		elif start == 'n':
			return self.decodeNull();
		else:
			Logger.quickLog("ch---" + start);
			raise GAEJsonException, "Invalid JSON string";

	def decodeTrue(self):
		if(self.getText(4, True) == "true"):
			return True;
		else:
			raise GAEJsonException, "Invalid True statement";


	def decodeFalse(self):
		if(self.getText(5, True) == "false"):
			return False;
		else:
			raise GAEJsonException, "Invalid False statement";

	def decodeNull(self):
		if(self.getText(4, True) == "null"):
			return None;
		else:
			raise GAEJsonException, "Invalid Null statement";


	def decodeNumber(self):
		isfloat = False;
		result = self.next();
		start = self.start();

		while start is not None and (start.isdigit() or start == "."):
			Logger.quickLog('no start--->' + start);
			
			isfloat = isfloat or start == "."
			result = result + self.next();
			start = self.start();

		try:
			if isfloat:
				return float(result);
			else:
				return int(result);
		except ValueError:
			raise GAEJsonException, "Not a valid number"



	def decodeString(self):
		result = ""
		assert self.next(True) == '"'
		try:
			while self.start() != '"':
				ch = self.next();
				
				if ch == "\\":
					ch = self.next();
					if ch in 'brnft':
						ch = self.escapes[ch];
					elif ch == "u":
						n = 4096 * self.hexToInt(self.next());
						n += 256 * self.hexToInt(self.next());
						n += 16  * self.hexToInt(self.next());
						n += self.hexToInt(self.next());
						ch = unichr(n);
					elif ch not in '"/\\':
						raise GAEJsonException, "Invalid escaped JSON character";
				result = result + ch;
		except StopIteration:
			Logger.QuickLog("start ch---- " + ch);
			raise GAEJsonException, "Invalid JSON string";
		assert self.next(True) == '"';
		return result;


	def decodeArray(self):
		result = [];
		assert self.next(True) == '[';
		end = self.start() == ']';
		
		while not end:
			item = self.startDecoding();
			result.append(item);
			
			end = self.start(True) == ']';
			if not end:
				ch = self.next();
			
				if ch != ",":
					raise GAEJsonException, "Invalid JSON array";
		assert ']' == self.next(True);
		return result;

	def decodeObject(self):
		result = {};
		assert self.next(True) == '{';
		end = self.start(True) == '}';

		while not end:
			key = self.startDecoding();

			if type(key) is not types.StringType:
				raise GAEJsonException, "Invalid JSON object key (should be a string)";

			ch = self.next(True);
		
			if ch != ":":
				raise GAEJsonException, "Invalid JSON object";

			val = self.startDecoding();
			result[key] = val;

			end = self.start(True) == '}';
			
			if not end:
				ch = self.next(True);
				if ch != ",":
					raise GAEJsonException, "Invalid JSON array";
		assert self.next(True) == "}";
		return result;

	def hexToInt(self, char):
		try:
			result = self.digits[char.upper()]
			return result;
		except ValueError:
			raise GAEJsonException, "Invalid hex digit. %s" + char;

	def start(self, skipWhiteSpace=False):
		i = self.index;

		if i < len(self.inputString):
			ch = self.inputString[i];

			i = i + 1

			while skipWhiteSpace and ch in string.whitespace:
				ch = self.inputString[i];
				i = i + 1
			
			return ch
		else:
			return None

	def next(self, skipWhiteSpace=False):

		if self.index < len(self.inputString):
			ch = self.inputString[self.index];
			self.index = self.index + 1;

			while skipWhiteSpace and ch in string.whitespace:
				ch = self.inputString[self.index];
				self.index = self.index + 1;
			
			return ch
		else:
			
			raise StopIteration

	def getText(self, number, skipWhiteSpace=False):
		if self.index < len(self.inputString):
			result = ""
			i = 0;
			while i < number:
				ch = self.next(skipWhiteSpace);
				result = result + ch;
				i = i + 1;

			return result
		else:
			return None

	
	
import sys, traceback
class Json(object):
    def write(self, obj, escaped_forward_slash=False):
	json = GaeJson();
	return json.encode(obj);
	#return JsonWriter().write(obj, escaped_forward_slash)

    def read(self, s):
        json = GaeJson();
	#try:
		
		#Logger.quickLog('json.decode' + JsonWriter().write(json.decode(s)))
		#Logger.quickLog('JsonReader' + JsonWriter().write(JsonReader().read(s)))
	#except:
		#Logger.quickLog(traceback.format_exc())
		#return HashMap();

	return json.decode(s);		
	#return JsonReader().read(s)
	

from FileManagerDB import *;
class FileManager:
    def __init__(self):
        self.__R = 'r';
        self.__W = 'w';
    @staticmethod
    def mkdir(dirname, perm = 0755):
	if(not Directory.is_exist(dirname)):
		try:
			directory = Directory()
			directory.directory_name = dirname;
			directory.put();
			return True
		except:
			return False;

	
	return True;
		



    @staticmethod
    def rmdir(dirname):
	if(Directory.is_exist(dirname)):
            directory.delete()
    @staticmethod
    def isdir(dirname):
        return Directory.is_exist(dirname);
    
    @staticmethod
    def fread(filepath):
        import os;
        dir_name = filepath.split(os.sep)[-2];
        file_name = filepath.split(os.sep)[-1];
        oFile = File.get(dir_name,file_name);
        if oFile:
            return oFile.content;

    @staticmethod
    def fwrite(filepath, content):
        import os;
        dir_name = filepath.split(os.sep)[-2];
        file_name = filepath.split(os.sep)[-1];
        if(not File.is_exist(dir_name,file_name)):
            oFile = File();
            oFile.directory_name = dir_name;
            oFile.file_name = file_name;
            oFile.content = content;
	    oFile.put();
	else :
            previous_version = File.get(directory_name, file_name);
	    previous_version.content = content;
	    previous_version.accessed_on = datetime.datetime.now();
            previous_version.put();

    @staticmethod
    def isfile(filepath):
        import os;
        dir_name = filepath.split(os.sep)[-2];
        file_name = filepath.split(os.sep)[-1];
        if(not File.is_exist(dir_name,file_name)):
	    return True;
	return False;

    @staticmethod
    def touch(filepath):
        import os;
        dir_name = filepath.split(os.sep)[-2];
        file_name = filepath.split(os.sep)[-1];
        if(not File.is_exist(dir_name,file_name)):
	    if(self.is_dir(dir_name)):
                oFile = File();
                oFile.directory_name = dir_name;
                oFile.file_name = file_name;
                oFile.put();
	else:
            previous_version = File.get(directory_name, file_name);
	    previous_version.accessed_on = datetime.datetime.now();
            previous_version.put();
                
    @staticmethod
    def unlink(filepath):
        import os;
        dir_name = filepath.split(os.sep)[-2];
        file_name = filepath.split(os.sep)[-1];
	file_id = File.is_exist(dir_name,file_name);
        oFile = File.get(dir_name,file_name);
        if oFile:
            oFile.delete()

class Serialize:
	def __init__(self, objectName):
		if(type(objectName).__name__ == 'dict'):
			return 'dict';
		elif(type(objectName).__name__ == 'instance'):
			return self.__objSerialize_(objectName);
		else:
			return None;

	def __objSerialize_(self, objectName):
		# prepare data for serialization
		serializedData = '';
		serializedData = 'O:' + str(len(objectName.__class__.__name__)) + ':"' + objectName.__class__.__name__ + '":';
		counter = 0;
		for attr in objectName.__dict__.iteritems():
			counter = counter + 1;
		serializedData = serializedData + str(counter) + ':{';
		for attr in objectName.__dict__.iteritems():
			if(type(attr[1]).__name__ == 'instance'):
				#private member
				serializedData = serializedData + self.__objSerialize_(attr[1]);
			else:
				#public member
				serializedData = serializedData + 's:' + str(len(attr[0])) + ':"' + attr[0] + '";' + self.__serialize_value_(attr[1]);

		serializedData = serializedData + '}';
		return serializedData;

	def __serialize_value_(self, data):
		"""
		Serialize a value.
		"""

		# Integer => integer
		if (type(data).__name__ == 'int'):
			return "i:%s;" % data

		# Float, Long => double
		elif type(data) is types.FloatType or type(data) is types.LongType:
			return "d:%s;" % data

		# String => string or String => int (if string looks like int)
		# Thanks to Todd DeLuca for noticing that PHP strings that
		# look like integers are serialized as ints by PHP 
		elif (type(data).__name__ == 'str'):
			return "s:%i:%s;" % (len(data), data);

		# None / NULL
		elif type(data) is types.NoneType:
			return "N;";

		# Tuple and List => array
		# The 'a' array type is the only kind of list supported by PHP.
		# array keys are automagically numbered up from 0
		elif type(data) is types.ListType or type(data) is types.TupleType:
			i = 0
			out = []
			# All arrays must have keys
			for k in data:
				out.append(self.serialize_key(i))
				out.append(self.serialize_value(k))
				i += 1
			return "a:%i:{%s}" % (len(data), "".join(out))

		# Dict => array
		# Dict is the Python analogy of a PHP array
		elif type(data) is types.DictType:
			out = []
			for k in data:
				out.append(self.serialize_key(k))
				out.append(self.serialize_value(data[k]))
			return "a:%i:{%s}" % (len(data), "".join(out))

		# Boolean => bool
		elif type(data) is types.BooleanType:
			if(data == True):
				return "b:1;";
			else:
				return "b:0;";

		# I dont know how to serialize this
		else:
			raise Exception("Unknown / Unhandled data type (%s)!" % type(data))
	def is_int(self, data):
		"""
		Determine if a string var looks like an integer
		TODO: Make this do what PHP does, instead of a hack
		"""
		try: 
			int(data)
			return True
		except:
			return False


class HashMap():
	def __init__(self, *args, **kwargs):
		self.__keys_ = [];
		self.__values_ = [];

		self.__index_ = 0;

		for value in args:
			key = value.keys()[0];
			
			self.__keys_.append(key)
			self.__values_.append(value[key]);


	def has_key(self, key):
		return key in self.__keys_;

	def len(self):
		return len(self.__keys_);

	def has_value(self, value):
		return value in self.__values_;
	
	def add(self, key, value):
		index = self.getKeyIndex(key);
		if (index != None):
			self.__values_[index] = value;
			return;
			

		self.__keys_.append(key);
		self.__values_.append(value);


	def destroy(self, key):
		index = self.getKeyIndex(key);
		if (index == None):
			return;

		del(self.__keys_[index]);
		del(self.__values_[index]);


	def getKeyIndex(self, search):		
		i = 0;
		for value in self.__keys_:
			if value == search:
				return i;

			i = i + 1;

		return None;
	
	def getKey(self, search):		
		i = 0;
		for value in self.__values_:			
			if value == search:
				return self.__keys_[i];

			i = i + 1;

		return None;

	def get(self, search):		
		return self.getValue(search);

	def getValue(self, search):		
		i = 0;
		for key in self.__keys_:			
			if key == search:
				return self.__values_[i];

			i = i + 1;

		return None;

	def enumerate(self):
		if(self.__index_ == len(self.__keys_)):
			return False;

		results = [];

		for i in range(len(self.__keys_)):
			results.append([self.__keys_[i], self.__values_[i]]);

		return results;

		key = self.__keys_[self.__index_];
		value = self.__values_[self.__index_];

		self.__index_ = self.__index_ + 1;

		return (key, value);

	def tostring(self):
		return 'code me please';

	def keys(self):
		return self.__keys_;
		
	def values(self):
		return self.__values_;

	def to_array(self):
		results = {};
		for i in range(len(self.__keys_)):
			results[self.__keys_[i]] = self.__values_[i];
		return results;

	def array_merge(self, arr):
		result = HashMap();

		for key in self.keys():
			result.add(key, self.get(key));
		
		for key in arr.keys():
			result.add(key, arr.get(key));

		return result;
		
		

from google.appengine.ext import db
class LogMessage(db.Model):
	id = db.StringProperty();
	filename = db.StringProperty(multiline=False);
	ip = db.StringProperty(multiline=False);
	message = db.TextProperty();
	priority = db.IntegerProperty();
	created_on = db.DateTimeProperty(auto_now_add=True);
	created_on_string = db.StringProperty(multiline=False);


class Logger:
	
	DEBUG = 0;
	INFO = 1;
	WARN = 2;
	ERROR = 3;
	CRITICAL = 4;

	DEFAULT_LIMIT = 500;

	priorities = {DEBUG: 'Debug', INFO: 'Info', WARN: 'Warn', ERROR: 'Error'};
	
	@staticmethod
	def getInstance():
		global loggerInstance;
		return loggerInstance;

	@staticmethod
	def quickLog(message, priority = DEBUG):
		global loggerInstance;

		loggerInstance.logMessage(message, priority);
		return;
		

	def __init__(self):
		self.minimumPriority = Logger.DEBUG

	def setPriority(self, priority):
		if(not priority in Logger.priorities.keys()):
			return;

		self.minimumPriority = priority;

	@staticmethod
	def getLogs():
		query = db.Query(LogMessage)
		query.order('-created_on')

		results = query.fetch(limit = Logger.DEFAULT_LIMIT)

		return results;

		#GqlQuery("SELECT * FROM LogMessage order by created_on desc")
		
		#query.fetch(Logger.DEFAULT_LIMIT);

	@staticmethod
	def clearLogs():
		from google.appengine.ext import db
		query = db.GqlQuery("SELECT * FROM LogMessage")

		results = query.fetch(100)

		if (len(results) ==0):
			return;

		db.delete(results);



	def __saveMessage_(self, message, logType = DEBUG):
		if(not self.__shouldSaveMessage_(message, logType)):
			return;
		

		formattedMessage = self.__formatMessage_(message, logType);

		import time;
		logTime = time.strftime('%Y-%m-%d %H:%M:%S');
		
		import os;
		client = os.environ['REMOTE_ADDR'];
		path = os.environ['PATH_INFO'];

		log = LogMessage(filename = path, message = formattedMessage, ip = client, priority = logType, created_on_string = logTime);

		log.put();
		


	def __shouldSaveMessage_(self, message, priority):
		if(not priority in Logger.priorities.keys() or priority < self.minimumPriority):
			return False;

		return True;
		

	def __formatMessage_(self, message, logType):
		#import time;
		#logTime = time.strftime('%a, %d %m %Y %H:%M:%S');

		#formattedMessage = message + logTime + ' - ' ;
		formattedMessage = message;

		return formattedMessage;
		
	@staticmethod
	def displayLog(log):
		
		formattedMessage = log.filename + " - ";
		formattedMessage = formattedMessage + Logger.priorities[log.priority] + ' ';
		formattedMessage = formattedMessage + '&lt;' + log.ip + '&gt;  ';

		formattedMessage = formattedMessage + log.created_on_string + ' - ' + log.message ;

		return formattedMessage;

	


	def logMessage(self, message, priority):
		
		self.__saveMessage_(message, priority);


	def debug(self, message):
		self.__saveMessage_(message, Logger.DEBUG);
		
	def info(self, message):
		self.__saveMessage_(message, Logger.INFO);

	def warn(self, message):
		self.__saveMessage_(message, Logger.WARN);

	def error(self, message):
		self.__saveMessage_(message, Logger.ERROR);

	def critical(self, message):
		self.__saveMessage_(message, Logger.CRITICAL);
		
loggerInstance = Logger();


from xml.dom import minidom
class Feed:

	@staticmethod
	def importString(domString) : 		
		dom = minidom.parseString(domString);
		#entries = Feed.getElement("entry", self.__dom_.firstChild)
		if(len(Feed.getElement("entry", dom.firstChild)) > 0):
			return FeedAtom(dom);
		elif(len(Feed.getElement("channel", dom.firstChild))):
			return FeedRss(dom);
		else:
			return None;					

	@staticmethod
	def getElement(elementName, object) : 
		#if(object == None):
			#object = self.__dom_;
		element = object.getElementsByTagName(elementName)
		if(len(element) > 0):
			if(len (element[0].childNodes) == 1):
				return element[0].firstChild.data;
			else:				
				elements = []
				for item in element:
					if item.parentNode.nodeName == object.nodeName:
						elements.append(item);
				return elements;
		else:
			return "";

class FeedAtom:
	def __init__(self, dom):
		self.__dom_ = dom;
		self.__title = Feed.getElement("title", self.__dom_.firstChild)
		self.__link = Feed.getElement("link", self.__dom_.firstChild)
		self.__id = Feed.getElement("id", self.__dom_.firstChild)
		self.__subtitle = Feed.getElement("subtitle", self.__dom_.firstChild)
		self.__entry = [];
		self.__setEntry_()

	def __setEntry_(self):
		entries = Feed.getElement("entry", self.__dom_.firstChild)
		entryObjects = [];
		for item in entries :
			entry = Entry();
			entry.setEntry(item);
			self.__entry.append(entry);		

			

	def title(self):
		return self.__title;
	
	def subtitle(self):
		return self.__subtitle;

	def link(self):
		return self.__link;

	def id(self):
		return self.__id;

	def entry(self):
		return self.__entry;

class Entry:
	def __init__(self) : 
		self.__title = "";
		self.__link = "";
		self.__id = ""
		self.__subtitle = "";
		self.__entry = "";
		self.__summary = "";
		self.__content = "";
		self.__author = "";
		self.__published = "";
		self.__updated = "";


	def setEntry(self, entry):
		self.__title = Feed.getElement("title", entry)
		self.__link = Feed.getElement("link", entry)
		self.__id = Feed.getElement("id", entry)
		self.__subtitle = Feed.getElement("subtitle", entry)
		self.__summary = Feed.getElement("summary", entry)
		self.__content = Feed.getElement("content", entry)
		self.__author = Feed.getElement("author", entry)
		self.__published = Feed.getElement("published", entry)
		self.__updated = Feed.getElement("updated", entry)

	def title(self):
		return self.__title;
	
	def id(self):
		return self.__id;
	
	def subtitle(self):
		return self.__subtitle;

	def link(self):
		return self.__link;

	def summary(self):
		return self.__summary;

	def content(self):
		return self.__content;

	def author(self):
		return self.__author;

	def published(self):
		return self.__published;

	def updated(self):
		return self.__updated;

class FeedRss:
	def __init__(self, dom):
		self.__dom_ = dom;
		channel = Feed.getElement("channel", self.__dom_.firstChild)[0]
		self.__title = Feed.getElement("title", channel)
		self.__link = Feed.getElement("link", channel)
		self.__description = Feed.getElement("description", channel)
		self.__pubDate = Feed.getElement("pubDate", channel)
		self.__language = Feed.getElement("language", channel)
		self.__category = Feed.getElement("category", channel)
		self.__items = [];
		self.__setItems_();
	
	def __setItems_(self):
		channel = Feed.getElement("channel", self.__dom_.firstChild)[0]
		items = Feed.getElement("item", channel)
		for item in items :
			itemObject = Item();
			itemObject.setItem(item);
			self.__items.append(itemObject);		

			

	def title(self):
		return self.__title;
	
	def description(self):
		return self.__description;

	def link(self):
		return self.__link;

	def pubDate(self):
		return self.__pubDate;

	def language(self):
		return self.__language;

	def category(self):
		return self.__category;

	def items(self):
		return self.__items;

class Item:
	def __init__(self):
		self.__title = ""
		self.__link = ""
		self.__description = ""
		self.__pubDate = ""
		self.__language = ""
		self.__category = ""
		self.__comments = ""

	def setItem(self, item):
		self.__title = Feed.getElement("title", item)
		self.__link = Feed.getElement("link", item)
		self.__description = Feed.getElement("description", item)
		self.__pubDate = Feed.getElement("pubDate", item)
		self.__language = Feed.getElement("language", item)
		self.__category = Feed.getElement("category", item)
		self.__comments = Feed.getElement("comments", item)


	def title(self):
		return self.__title;
	
	def description(self):
		return self.__description;

	def link(self):
		return self.__link;

	def pubDate(self):
		return self.__pubDate;

	def language(self):
		return self.__language;

	def category(self):
		return self.__category;

	def comments(self):
		return self.__comments;



import xmllib, string;
from xml.etree import ElementTree;

class XmlBuilder(xmllib.XMLParser):

    def __init__(self, html=0):
        self.__parser = ElementTree.TreeBuilder()
        if html:
            import htmlentitydefs
            self.entitydefs.update(htmlentitydefs.entitydefs)
        xmllib.XMLParser.__init__(self)

    def feed(self, data):
        xmllib.XMLParser.feed(self, data)


    def close(self):
        xmllib.XMLParser.close(self)
        return self.__parser.close()

    def handle_data(self, data):
        self.__parser.data(data)

    handle_cdata = handle_data

    def unknown_starttag(self, tag, attrs):
	global xmlBuilderHandler;
        attrib = {}
        for key, value in attrs.items():
            attrib[xmlBuilderHandler.fixTag(key)] = value
        self.__parser.start(xmlBuilderHandler.fixTag(tag), attrib)

    def unknown_endtag(self, tag):
	global xmlBuilderHandler;
        self.__parser.end(xmlBuilderHandler.fixTag(tag))

    @staticmethod
    def fixTag(name, split=string.split):
        if " " not in name:
            return name
        return "{%s}%s" % tuple(split(name, " ", 1))



xmlBuilderHandler = XmlBuilder();
